const express = require('express');
const router = express.Router();
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const crypto = require('crypto');
const fileTmp = path.join(__dirname, '../tmp');
const FilePak = require('../lib/FilePak');
const bin = multer({
    dest: fileTmp,
    fileFilter: fileFilter
}); //用来保存文件的文件夹名称

const fileMap = new Map();

router.all('/', function (req, res, next) {
    req.peTime = new Date().getTime();
    return next();
});
/* GET users listing. */
router.get('/', function (req, res, next) {
    let {upload_to, name, chunk, chunks} = req.query;
    res.send(new Message(false, new Date().getTime(), 'not_exists'));
});

//过滤器
function fileFilter(req, file, cb) {
    let {id, type, lastModifiedDate, upload_to, check_md5, name, size, chunks, chunk} = req.body;
    if (!chunks) { //未分段上传
        return cb(null, true);
    } else {
        //计算文件md5取得唯一id;
        let sign = md5(id + name + type + lastModifiedDate + upload_to + size + chunks);
        req.filePak = fileMap.get(sign)||new FilePak(req.body, sign);
        fileMap.set(sign,req.filePak);
        return cb(null, true);
    }
}

//处理文件
router.post('/', bin.single('file'), function (req, res, next) {
    let {upload_to, check_md5, name, size, chunks, chunk} = req.body;
    let filePath = path.join(upload_to, name); //储存文件路径
    if (!req.file) return res.send(new Message(false,req["peTime"],'no-file'));
    let message = new Message(true, req["peTime"], 'upload_success');
    console.log('分段接收完成:' + chunk);
    if (!chunks) { //只有一个分段
        if (size !== req.file.size.toString()) {
            fs.unlinkSync(req.file.path);
            return res.send(new Message(false, req["peTime"], 'bad file'))
        }
        fs.renameSync(req.file.path, filePath);
        message.info = filePath;
        res.send(message);
    } else {
        let b = req["filePak"].addChunkData(req.file, chunk);
        if (b) {
            req["filePak"].save().then((p) => {
                fileMap.delete(req["filePak"].sign);
                let message = new Message(true, req["peTime"], 'upload_success');
                message.info = p;
                return res.send(message);
            }).catch((err) => {
                console.log('文件合并出错');
                console.log(err);
                let message = new Message(false, req["peTime"], '合并文件出错');
                return res.send(message);
            })
        } else return res.send(message);
    }
});


function md5(s) {
    let h = crypto.createHash('md5');
    return h.update(s).digest('hex');
}

function Message(code = false, use_time = 0, data = "") {
    this.code = code;
    this.use_time = (new Date().getTime()) - use_time;
    this.data = data;
}

Message.prototype.toString = function () {
    return JSON.stringify(this);
}
module.exports = router;